﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Lilium.LExpress
{
    internal static class Transform
    {
        public static void SubstituteSubexpressions(this Expression expr, IDictionary<Expression, Expression> substitutions)
        {
            throw new NotImplementedException();
        }

        #region SingleSubstitutionDictionary

        private sealed class SingleSubstitutionDictionary : IDictionary<Expression, Expression>
        {
            public SingleSubstitutionDictionary(Expression key, Expression value)
            {
                if (key == null) throw new ArgumentNullException("key");
                if (value == null) throw new ArgumentNullException("value");

                Key = key;
                Value = value;
            }

            #region IDictionary<Expression,Expression> Members

            public void Add(Expression key, Expression value)
            {
                throw new NotSupportedException();
            }

            public bool ContainsKey(Expression key)
            {
                return Key == key;
            }

            public ICollection<Expression> Keys
            {
                get { return new Expression[] { Key }; }
            }

            public bool Remove(Expression key)
            {
                throw new NotSupportedException();
            }

            public bool TryGetValue(Expression key, out Expression value)
            {
                if (key == Key)
                {
                    value = Value;
                    return true;
                }
                else
                {
                    value = null;
                    return false;
                }
            }

            public ICollection<Expression> Values
            {
                get { return new Expression[] { Value }; }
            }

            public Expression this[Expression key]
            {
                get
                {
                    if (key == Key)
                        return Value;
                    else
                        throw new KeyNotFoundException();
                }
                set
                {
                    throw new NotSupportedException();
                }
            }

            #endregion

            #region ICollection<KeyValuePair<Expression,Expression>> Members

            public void Add(KeyValuePair<Expression, Expression> item)
            {
                throw new NotSupportedException();
            }

            public void Clear()
            {
                throw new NotSupportedException();
            }

            public bool Contains(KeyValuePair<Expression, Expression> item)
            {
                return Key == item.Key && Value == item.Value;
            }

            public void CopyTo(KeyValuePair<Expression, Expression>[] array, int arrayIndex)
            {
                array[arrayIndex] = new KeyValuePair<Expression, Expression>(Key, Value);
            }

            public int Count
            {
                get { return 1; }
            }

            public bool IsReadOnly
            {
                get { return true; }
            }

            public bool Remove(KeyValuePair<Expression, Expression> item)
            {
                throw new NotSupportedException();
            }

            #endregion

            #region IEnumerable<KeyValuePair<Expression,Expression>> Members

            public IEnumerator<KeyValuePair<Expression, Expression>> GetEnumerator()
            {
                yield return new KeyValuePair<Expression, Expression>(Key, Value);
            }

            #endregion

            #region IEnumerable Members

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }

            #endregion

            private readonly Expression Key;
            private readonly Expression Value;
        }


        #endregion
    }
}
